package fileSplit;

import org.apache.commons.lang3.StringUtils;

import java.io.*;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;

/**
 * @Author lxy
 * @Date 2021/12/27 22:08
 * @Description
 */
public class FileSplit {
    public static void main(String[] args) {
//        File file = new File("F:\\k\\test\\test.sql");
//        System.out.println(file.getPath()+"  "+file.length());
        splitBySize("F:\\k\\test\\test.sql",500);
    }
    public static List<String> splitBySize(String fileName, int byteSize){
        List<String> parts = new ArrayList<String>();
        File file = new File(fileName);
        //文件的总长度除以要拆分的大小，得出的结果是拆分后的分片数量
        int count = (int) Math.ceil(file.length() / (double) byteSize);
        ThreadPoolExecutor threadPool = new ThreadPoolExecutor(
                    count,
                    count * 3,
                    1,
                    TimeUnit.SECONDS,
                    new ArrayBlockingQueue<Runnable>(count * 2));
        for (int i = 0; i < count; i++) {
            String partFileName = file.getName() + "." + StringUtils.leftPad((i + 1) + "", (count+"").length(), '0') + ".part";
            threadPool.execute(new SplitRunnable(byteSize, i * byteSize,partFileName, file));
            parts.add(partFileName);
        }
        return parts;
    }

    private static class SplitRunnable implements Runnable {
        int byteSize;
        String partFileName;
        File originFile;
        int startPos;
        public SplitRunnable(int byteSize, int startPos, String partFileName, File originFile) {
             this.startPos = startPos;
             this.byteSize = byteSize;
             this.partFileName = partFileName;
             this.originFile = originFile;
         }

        @Override
        public void run() {
             RandomAccessFile rFile;
             OutputStream os;
             try {
                 rFile = new RandomAccessFile(originFile, "r");
                 byte[] b = new byte[byteSize];
                 rFile.seek(startPos);// 移动指针到每“段”开头
                 int s = rFile.read(b);
                 os = new FileOutputStream(partFileName);
                 os.write(b, 0, s);
                 os.flush();
                 os.close();
             } catch (IOException e) {
                 e.printStackTrace();
             }
         }
    }
}
